package com.sky.service.user.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.sky.constant.MessageConstant;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.admin.MerchantMapper;
import com.sky.mapper.courier.CourierTradeOrderMapper;
import com.sky.mapper.user.OrderMapper;
import com.sky.pojo.Courier;
import com.sky.pojo.CourierTradeOrder;
import com.sky.pojo.Merchant;
import com.sky.pojo.Orders;
import com.sky.service.courier.CourierService;
import com.sky.service.user.OrderDispatchService;
import com.sky.service.user.OrderService;
import com.sky.vo.OrderVO;
import com.sky.webscoket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description OrderDispatchServiceImpl
 * @Author lyh
 * @Date 2024-10-21
 */
@Service
public class OrderDispatchServiceImpl implements OrderDispatchService {
   @Autowired
   private OrderService orderService;
   @Autowired
   private CourierService courierService;
   @Autowired
   private CourierTradeOrderMapper courierTradeOrderMapper;
   @Autowired
   private MerchantMapper merchantMapper;
   @Autowired
   private OrderMapper orderMapper;


    @Override
    public Courier dispatchCourier(Orders orders, Long tradeNo, Long courierId) {
        //return Courier.builder().name("张三").build();
        OrderVO orderVO=null;
        if(orders!=null && orders.getId()!=null) {
            orderVO = orderService.getOrderDetatl(orders.getId());
        }
        if(tradeNo!=null){
            CourierTradeOrder tradeOrder = courierTradeOrderMapper.queryCanceldTradeOrderByTradeNo(String.valueOf(tradeNo));

         orderVO =orderMapper.selectByOrderNumber(tradeOrder.getOrderNumber());
        }
        if(orderVO==null){
            throw  new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //找骑手
        //        1.优先查询商家10公里内的在职骑手  -- 多个骑手
        List<Courier> list= courierService.findCourierNearMerchant(orderVO.getShopId());

//        2.然后考虑上述骑手中，订单量最少的骑手
        if(list==null||list.size()==0){
            return null;
        }
        list=list.stream().filter(courier -> {
            return !courier.getId().equals(courierId);
        }).collect(Collectors.toList());
        List<Long> courierIds = list.stream().map(courier -> {
                return courier.getId();
        }).collect(Collectors.toList());
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        List<Map<String,Long>> countCourierOrders=courierTradeOrderMapper.CountCourierOrderByIds(courierIds,today);
        System.out.println(countCourierOrders);
        //获取最小单的数量
        Long minNum = countCourierOrders.stream().min(Comparator.comparing(map -> {
            return map.get("total");
        })).get().get("total");
 //        3.找出最小订单相近的骑手（3单以内）  -- 比如最小订单数是10，那么找出订单量10,11,12,13的骑手   --多个骑手
        courierIds = countCourierOrders.stream().filter(map -> {
            return map.get("total") <= minNum + 3;
        }).map(map -> {
            return map.get("id");
        }).collect(Collectors.toList());
        System.out.println(courierIds);
//        4.骑手的待接单和已接单（骑手正在进行中的订单）不能超过12
        courierIds =courierTradeOrderMapper.findTodayOrdersLessThen12ByIds(courierIds,today);
//        5.按照上述规则条件如果没有找到，从最初的10公里内的骑手中随机挑选一个
        if(courierIds.size()==0){
            int index= new Random().nextInt(list.size());
            courierIds.add(list.get(index).getId());
        }
        List<Long> courierIds2=courierIds;
//        6.然后从所有满足条件的骑手中，找到评分最高的做为最终骑手进行派单
        Courier finalCourier = list.stream().filter(courier -> {
            return courierIds2.contains(courier.getId());
        }).sorted(Comparator.comparing(Courier::getScore).reversed())
                .collect(Collectors.toList()).get(0);
        //封装运单
        saveTradeOrder(orderVO,finalCourier,tradeNo);
        notifyCourier(finalCourier.getId(),orderVO.getNumber());
        return finalCourier;
    }

    @Autowired
    private WebSocketServer webSocketServer;
    private void notifyCourier(Long courierId,String orderNumber){
     Map<String,Object> map= new HashMap<>();
     map.put("tradeNo",orderNumber);
     map.put("code",1);
     map.put("msg","你有新的待接单，请及时查收");
      String message= JSON.toJSONString(map);
      webSocketServer.sendRiderInfo(message,courierId);
    }
    private void saveTradeOrder(OrderVO orderVO, Courier finalCourier,Long tradeNo) {
        if(tradeNo!=null){
            courierTradeOrderMapper.updateCourierIdByTradeNo(finalCourier.getId(),tradeNo);
            return;
        }
        Merchant merchant = merchantMapper.selectById(orderVO.getShopId());
        //计算配送费
        double deliveryFee = orderVO.getDeliveryFee().doubleValue();
        //计算提成
        /**
         * - 1 公里内                  3块    取5成
         * - 超出1公里部分 少于3公里部分  3-5   取6成
         * - 超出3公里部分  0.7         >5    取7成
         *    公里数换算成配送费
         */
        BigDecimal courierCost=null;
        if(deliveryFee<=3){
            courierCost=BigDecimal.valueOf(1.5);
        }else if(deliveryFee>3&&deliveryFee<=5){
            courierCost=BigDecimal.valueOf(1.5);//基础费用
            BigDecimal otherCost = BigDecimal.valueOf(deliveryFee - 3).multiply(BigDecimal.valueOf(0.6));
            courierCost=courierCost.add(otherCost);
        }else if(deliveryFee>5){
            courierCost = BigDecimal.valueOf(1.5);// 基础非
            BigDecimal other1Cost = BigDecimal.valueOf(1.2); //介于1到3公里之间的费用
            BigDecimal endCost = BigDecimal.valueOf(deliveryFee-5).multiply(BigDecimal.valueOf(0.7));
            courierCost = courierCost.add(other1Cost);
            courierCost = courierCost.add(endCost);
        }
        CourierTradeOrder courierTradeOrder=CourierTradeOrder.builder()
                .totalAmount(orderVO.getAmount())
                .courierId(finalCourier.getId())
                .orderNumber(orderVO.getNumber())
                .waybillStatus(CourierTradeOrder.DISPATCH_OK) //1 ： 待接单
                .tradeCreateTime(LocalDateTime.now())
                .shopAddress(merchant.getShopAddress())
                .remark(orderVO.getRemark())
                .customerAddress(orderVO.getAddress())  //客户地址
                .customerExpectedDeliveryTime(orderVO.getEstimatedDeliveryTime()) //预计送达时间
                .customerName(orderVO.getConsignee())
                .shopName(merchant.getShopName())
                .telephone(orderVO.getPhone())
                .toBeMealTime(orderVO.getMealTime())
                .income(courierCost)
                .build();
        //入库
        courierTradeOrderMapper.save(courierTradeOrder);
    }
}
